﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace yt
{
       
    public static class WinAPI
    {
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

        [DllImport("user32.dll")]
        public static extern long EnumChildWindows(IntPtr hWndParent, frmMain.EnumChildWindowsProc lpEnumFunc, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
        ///<summary>
        /// 该函数设置由不同线程产生的窗口的显示状态
        /// </summary>
        /// <param name="hWnd">窗口句柄</param>
        /// <param name="cmdShow">指定窗口如何显示。查看允许值列表，请查阅ShowWlndow函数的说明部分</param>
        /// <returns>如果函数原来可见，返回值为非零；如果函数原来被隐藏，返回值为零</returns>
        [DllImport("User32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);


        /// <summary>
        ///  该函数将创建指定窗口的线程设置到前台，并且激活该窗口。键盘输入转向该窗口，并为用户改各种可视的记号。
        ///  系统给创建前台窗口的线程分配的权限稍高于其他线程。 
        /// </summary>
        /// <param name="hWnd">将被激活并被调入前台的窗口句柄</param>
        /// <returns>如果窗口设入了前台，返回值为非零；如果窗口未被设入前台，返回值为零</returns>
        [DllImport("User32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("kernel32.dll")]
        static extern uint GetTickCount();

        [DllImport("user32")]
        public static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);

        public static uint WM_KEYDOWN = 0x0100;
        public static uint WM_KEYUP = 0x0101;
        public static int WM_SYSKEYDOWN = 0x0104;
        public static int WM_SYSKEYUP = 0x0105;

        public static uint WM_MOUSEMOVE = 0x0200;
        public static uint WM_LBUTTONDOWN = 0x0201;
        public static uint WM_LBUTTONUP = 0x0202;
        public static int WM_LBUTTONDBLCLK = 0x0203;
        public static int WM_RBUTTONDOWN = 0x0204;
        public static int WM_RBUTTONUP = 0x0205;
        public static int WM_RBUTTONDBLCLK = 0x0206;
        public static int WM_USER = 0x0400;

        public static int MK_LBUTTON = 0x0001;
        public static int MK_RBUTTON = 0x0002;
        public static int MK_SHIFT = 0x0004;
        public static int MK_CONTROL = 0x0008;
        public static int MK_MBUTTON = 0x0010;

        public static int MK_XBUTTON1 = 0x0020;
        public static int MK_XBUTTON2 = 0x0040;


        public const uint WM_CHAR = 0x0102;
        //public const int VK_TAB = 0x09;
        public const int VK_ENTER = 0x0D;
        //public const int VK_UP = 0x26;
        //public const int VK_DOWN = 0x28;
        //public const int VK_RIGHT = 0x27;

        

       

        public const int SW_SHOWNOMAL = 1;
        public const int SW_SHOWMAXIMIZED = 3;

        //Windows 使用的256个虚拟键码
        public const int VK_LBUTTON = 0x1;
        public const int VK_RBUTTON = 0x2;
        public const int VK_CANCEL = 0x3;
        public const int VK_MBUTTON = 0x4;
        public const int VK_BACK = 0x8;
        public const int VK_TAB = 0x9;
        public const int VK_CLEAR = 0xC;
        public const int VK_RETURN = 0xD;
        public const int VK_SHIFT = 0x10;
        public const int VK_CONTROL = 0x11;
        public const int VK_MENU = 0x12;
        public const int VK_PAUSE = 0x13;
        public const int VK_CAPITAL = 0x14;
        public const int VK_ESCAPE = 0x1B;
        public const int VK_SPACE = 0x20;
        public const int VK_PRIOR = 0x21;
        public const int VK_NEXT = 0x22;
        public const int VK_END = 0x23;
        public const int VK_HOME = 0x24;
        public const int VK_LEFT = 0x25;
        public const int VK_UP = 0x26;
        public const int VK_RIGHT = 0x27;
        public const int VK_DOWN = 0x28;
        public const int VK_Select = 0x29;
        public const int VK_PRINT = 0x2A;
        public const int VK_EXECUTE = 0x2B;
        public const int VK_SNAPSHOT = 0x2C;
        public const int VK_Insert = 0x2D;
        public const int VK_Delete = 0x2E;
        public const int VK_HELP = 0x2F;
        public const int VK_0 = 0x30;
        public const int VK_1 = 0x31;
        public const int VK_2 = 0x32;
        public const int VK_3 = 0x33;
        public const int VK_4 = 0x34;
        public const int VK_5 = 0x35;
        public const int VK_6 = 0x36;
        public const int VK_7 = 0x37;
        public const int VK_8 = 0x38;
        public const int VK_9 = 0x39;
        public const int VK_A = 0x41;
        public const int VK_B = 0x42;
        public const int VK_C = 0x43;
        public const int VK_D = 0x44;
        public const int VK_E = 0x45;
        public const int VK_F = 0x46;
        public const int VK_G = 0x47;
        public const int VK_H = 0x48;
        public const int VK_I = 0x49;
        public const int VK_J = 0x4A;
        public const int VK_K = 0x4B;
        public const int VK_L = 0x4C;
        public const int VK_M = 0x4D;
        public const int VK_N = 0x4E;
        public const int VK_O = 0x4F;
        public const int VK_P = 0x50;
        public const int VK_Q = 0x51;
        public const int VK_R = 0x52;
        public const int VK_S = 0x53;
        public const int VK_T = 0x54;
        public const int VK_U = 0x55;
        public const int VK_V = 0x56;
        public const int VK_W = 0x57;
        public const int VK_X = 0x58;
        public const int VK_Y = 0x59;
        public const int VK_Z = 0x5A;
        public const int VK_STARTKEY = 0x5B;
        public const int VK_CONTEXTKEY = 0x5D;
        public const int VK_NUMPAD0 = 0x60;
        public const int VK_NUMPAD1 = 0x61;
        public const int VK_NUMPAD2 = 0x62;
        public const int VK_NUMPAD3 = 0x63;
        public const int VK_NUMPAD4 = 0x64;
        public const int VK_NUMPAD5 = 0x65;
        public const int VK_NUMPAD6 = 0x66;
        public const int VK_NUMPAD7 = 0x67;
        public const int VK_NUMPAD8 = 0x68;
        public const int VK_NUMPAD9 = 0x69;
        public const int VK_MULTIPLY = 0x6A;
        public const int VK_ADD = 0x6B;
        public const int VK_SEPARATOR = 0x6C;
        public const int VK_SUBTRACT = 0x6D;
        public const int VK_DECIMAL = 0x6E;
        public const int VK_DIVIDE = 0x6F;
        public const int VK_F1 = 0x70;
        public const int VK_F2 = 0x71;
        public const int VK_F3 = 0x72;
        public const int VK_F4 = 0x73;
        public const int VK_F5 = 0x74;
        public const int VK_F6 = 0x75;
        public const int VK_F7 = 0x76;
        public const int VK_F8 = 0x77;
        public const int VK_F9 = 0x78;
        public const int VK_F10 = 0x79;
        public const int VK_F11 = 0x7A;
        public const int VK_F12 = 0x7B;
        public const int VK_F13 = 0x7C;
        public const int VK_F14 = 0x7D;
        public const int VK_F15 = 0x7E;
        public const int VK_F16 = 0x7F;
        public const int VK_F17 = 0x80;
        public const int VK_F18 = 0x81;
        public const int VK_F19 = 0x82;
        public const int VK_F20 = 0x83;
        public const int VK_F21 = 0x84;
        public const int VK_F22 = 0x85;
        public const int VK_F23 = 0x86;
        public const int VK_F24 = 0x87;
        public const int VK_NUMLOCK = 0x90;
        public const int VK_OEM_SCROLL = 0x91;
        public const int VK_OEM_1 = 0xBA;
        public const int VK_OEM_PLUS = 0xBB;
        public const int VK_OEM_COMMA = 0xBC;
        public const int VK_OEM_MINUS = 0xBD;
        public const int VK_OEM_PERIOD = 0xBE;
        public const int VK_OEM_2 = 0xBF;
        public const int VK_OEM_3 = 0xC0;
        public const int VK_OEM_4 = 0xDB;
        public const int VK_OEM_5 = 0xDC;
        public const int VK_OEM_6 = 0xDD;
        public const int VK_OEM_7 = 0xDE;
        public const int VK_OEM_8 = 0xDF;
        public const int VK_ICO_F17 = 0xE0;
        public const int VK_ICO_F18 = 0xE1;
        public const int VK_OEM102 = 0xE2;
        public const int VK_ICO_HELP = 0xE3;
        public const int VK_ICO_00 = 0xE4;
        public const int VK_ICO_CLEAR = 0xE6;
        public const int VK_OEM_RESET = 0xE9;
        public const int VK_OEM_JUMP = 0xEA;
        public const int VK_OEM_PA1 = 0xEB;
        public const int VK_OEM_PA2 = 0xEC;
        public const int VK_OEM_PA3 = 0xED;
        public const int VK_OEM_WSCTRL = 0xEE;
        public const int VK_OEM_CUSEL = 0xEF;
        public const int VK_OEM_ATTN = 0xF0;
        public const int VK_OEM_FINNISH = 0xF1;
        public const int VK_OEM_COPY = 0xF2;
        public const int VK_OEM_AUTO = 0xF3;
        public const int VK_OEM_ENLW = 0xF4;
        public const int VK_OEM_BACKTAB = 0xF5;
        public const int VK_ATTN = 0xF6;
        public const int VK_CRSEL = 0xF7;
        public const int VK_EXSEL = 0xF8;
        public const int VK_EREOF = 0xF9;
        public const int VK_PLAY = 0xFA;
        public const int VK_ZOOM = 0xFB;
        public const int VK_NONAME = 0xFC;
        public const int VK_PA1 = 0xFD;
        public const int VK_OEM_CLEAR = 0xFE;
        
//按照以上对照表 写快捷键 CTRL + F :

//SendMessage(hwnd, 0x0104, 0x11, 0x20380001);//0x11 == VK_CONTROL == ALT键

//SendMessage(hwnd, 0x0104, (int)'F', 0x20210001);//

//SendMessage(hwnd, 0x0106, (int)'f', 0x20210001);// 
//SendMessage(hwnd, 0x0105, (int)'F', 0xE0210001);//
//SendMessage(hwnd, 0x0105, 0x11, 0xC0380001);//

//忘记说了 关于参数 lParam 是这么说的:

        //鼠标事件  因为我用的不多，所以其他参数没有写
        //private const int MOUSEEVENTF_LEFTDOWN = 0x0002;//模拟鼠标移动
        //private const int MOUSEEVENTF_MOVE = 0x0001;//模拟鼠标左键按下
        //private const int MOUSEEVENTF_LEFTUP = 0x0004;//模拟鼠标左键抬起
        //private const int MOUSEEVENTF_ABSOLUTE = 0x8000;//鼠标绝对位置
        //private const int MOUSEEVENTF_RIGHTDOWN = 0x0008; //模拟鼠标右键按下 
        //private const int MOUSEEVENTF_RIGHTUP = 0x0010; //模拟鼠标右键抬起 
        //private const int MOUSEEVENTF_MIDDLEDOWN = 0x0020; //模拟鼠标中键按下 
        //private const int MOUSEEVENTF_MIDDLEUP = 0x0040;// 模拟鼠标中键抬起 
        

        //According to SPY++ in IE

        //ENTER key is
        // P KEYDOWN
        // P CHAR
        // S CHAR
        // P KEY_UP

        //TAB key is
        // P KEYDOWN
        // P KEYUP

        //DOWN, UP, RIGHT, LEFT is
        // P KEYDOWN
        // S KEYDOWN
        // P KEYUP

        //Letters is
        // P KEYDOWN
        // S KEYDOWN
        // P CHAR
        // S CHAR
        // P KEYUP
        public static void SendKey(IntPtr handle,int key)
        {
            PostMessage(handle, WM_KEYDOWN, (IntPtr)key, IntPtr.Zero);
            PostMessage(handle, WM_KEYUP, (IntPtr)key, IntPtr.Zero);
        }

        public static void SendESC(IntPtr handle)
        {
            PostMessage(handle, WM_KEYDOWN, (IntPtr) VK_ESCAPE, IntPtr.Zero);
            PostMessage(handle, WM_KEYUP, (IntPtr)VK_ESCAPE, IntPtr.Zero);
        }

        private static void SendEnter(IntPtr handle)
        {
            PostMessage(handle, WM_KEYDOWN, (IntPtr)VK_ENTER, IntPtr.Zero);
            PostMessage(handle, WM_CHAR, (IntPtr)VK_ENTER, IntPtr.Zero);
            SendMessage(handle, WM_CHAR, (IntPtr)VK_ENTER, IntPtr.Zero);
            PostMessage(handle, WM_KEYUP, (IntPtr)VK_ENTER, IntPtr.Zero);
        }

        private static void SendTab(IntPtr handle)
        {
            PostMessage(handle, WM_KEYDOWN, (IntPtr)VK_TAB, IntPtr.Zero);
            PostMessage(handle, WM_KEYUP, (IntPtr)VK_TAB, IntPtr.Zero);
        }


        private static void SendArrowKey(IntPtr handle, int key)
        {
            PostMessage(handle, WM_KEYDOWN, (IntPtr)key, IntPtr.Zero);
            SendMessage(handle, WM_KEYDOWN, (IntPtr)key, IntPtr.Zero);
            PostMessage(handle, WM_KEYUP, (IntPtr)key, IntPtr.Zero);
        }

        private static void SendChar(IntPtr handle, int key)
        {
            //Keydown wParam values are 0x020 less than WM_CHAR wParam
            PostMessage(handle, WM_KEYDOWN, (IntPtr)(key - 0x020), IntPtr.Zero);
            SendMessage(handle, WM_KEYDOWN, (IntPtr)(key - 0x020), IntPtr.Zero);
            PostMessage(handle, WM_CHAR, (IntPtr)key, IntPtr.Zero);
            SendMessage(handle, WM_CHAR, (IntPtr)key, IntPtr.Zero);
            PostMessage(handle, WM_KEYUP, (IntPtr)(key - 0x020), IntPtr.Zero);
        }

        public static int MakeLParam(int wLow, int wHigh)
        {
            return (int)((wHigh << 16) | (wLow & 0xffff));
        }

        public static IntPtr MakeLParam(Point p)
        {
            return (IntPtr)((p.Y << 16) | (p.X & 0xffff));
        }
        public static void SendClick(IntPtr winhandle, IntPtr handle, Point p)
        {
            //StringBuilder className = new StringBuilder(100);
            //GetClassName(handle, className, className.Capacity);
            //MessageBox.Show(className.ToString());

            //string cn = className.ToString();
            //if (className.ToString() == "MacromediaFlashPlayerActiveX")
            //{
            // Point point = GetFlashPointFromHandle(handle);
            // if (point.X == ((webBrowser1.Document.DomDocument) as HTMLDocument).getElementById("obj1").offsetLeft && point.Y == ((webBrowser1.Document.DomDocument) as HTMLDocument).getElementById("obj1").offsetTop)
            // {
            //webBrowser1.Document.Body.ScrollTop = 100;WM_MOUSEMOVE
            //dx=x*(65535/screenx)-> x=dx*screenx/65535
            //dy=y*(65536/screeny)-> y=dy*screenx/65535
            //int screenx = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
            //int screeny = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
            //Point fixP = new Point();
            //fixP.X = (int) (((double) p.X/1600)*(double) screenx);
            //fixP.Y = (p.Y / 900) * screeny;
            //ShowWindowAsync(winhandle, SW_SHOWMAXIMIZED);//显示
            //SetForegroundWindow(winhandle);//当到最前端
            PostMessage(handle, WM_MOUSEMOVE, (IntPtr)MK_LBUTTON, MakeLParam(p));
            PostMessage(handle, WM_LBUTTONDOWN, (IntPtr)MK_LBUTTON, MakeLParam(p));
            PostMessage(handle, WM_LBUTTONUP, (IntPtr)MK_LBUTTON, MakeLParam(p));

            //SendMessage(handle, WM_KEYDOWN, (IntPtr)VK_ENTER, IntPtr.Zero);
            //SendMessage(handle, WM_KEYUP, (IntPtr)VK_ENTER, IntPtr.Zero);
            //SendMessage(handle, WM_KEYDOWN, (IntPtr)13, lParam);
            //SendMessage(handle, WM_KEYUP, (IntPtr)13, lParam);
            //}
            //}

        }

        public static void Delay(int ms)
        {
            uint start = GetTickCount();
            while (GetTickCount() - start < ms)
            {
                Application.DoEvents();
            }
        }

        public static void ShowWindows(IntPtr handle, int stat)
        {
            if (stat==0)
            {
                ShowWindowAsync(handle, SW_SHOWNOMAL);//显示
                //ShowWindowAsync(this.Handle, SW_SHOWMAXIMIZED);//显示
                SetForegroundWindow(handle);//当到最前端
            }
            else
            {
                //ShowWindowAsync(this.Handle, SW_SHOWNOMAL);//显示
                ShowWindowAsync(handle, SW_SHOWMAXIMIZED);//显示
                SetForegroundWindow(handle);//当到最前端
            }
            
        }
    }
}
